www.gusucode.com > VC++ 编写软件自动升级服务源代码 > VC++ 编写软件自动升级服务源代码/gusucode/updater_src0.8.1.6/GetOpt.cpp
/*******************************************************************| | | | GetOpt.cpp | | Geert van Horrik, visit http://www.gvhsoftware.org | | Version: 1.1 | | Date: 2006-03-07 | | | | License: | | This software is released into the public domain. You | | are free to use it in any way you like, except that you | | may not sell this source code. | | | | This software is provided "as is" with no expressed or | | implied warranty. I accept no liability for any damage or | | loss of business that this software may cause. | | | |*******************************************************************/ //******************************************************************** // INCLUDES //******************************************************************** #include "stdafx.h" #include "GetOpt.h" #include <algorithm> #include <cstdlib> //******************************************************************* // CONSTRUCTOR & DESTRUCTOR //******************************************************************* CGetOpt::CGetOpt() { // Initialize variables m_bCompareCaseSensitive = false; // Clear results ResetParamData(); } //=================================================================== CGetOpt::~CGetOpt() { } //******************************************************************* // PUBLIC FUNCTIONS //******************************************************************* void CGetOpt::CompareCaseSensitive(bool bCaseSensitive /* = false */) { // Set value m_bCompareCaseSensitive = bCaseSensitive; } //=================================================================== void CGetOpt::AddExpectedParameter(string sParameter, bool bValueExpected /* = true */, ParameterType oParamType /* = PARAMETERTYPE_UNKNOWN */) { // Declare variables Param oParamInfo; // Add values to parameter info oParamInfo.sParameter = sParameter; oParamInfo.bValueExpected = bValueExpected; oParamInfo.oType = oParamType; // Add struct to array m_arrParametersExpected[m_iParamExpectedCount++] = oParamInfo; } //=================================================================== void CGetOpt::ParseCommandLine(string sCommandLine) { // Declare variables int iParameterIndex; string sParameter, sValue; // Reset old data m_iParamUsedCount = 0; // Loop as long as we have a parameter line while (sCommandLine.length() > 0) { // Clear previous data sParameter = ""; sValue = ""; // Trim spaces from command line sCommandLine = TrimSpaces(sCommandLine); // Get first block (quotes are not allowed) sParameter = GetFirstTextBlock(sCommandLine, false); // Strip parameter sCommandLine.erase(0, sParameter.length() + 1); // Trim spaces from command line sCommandLine = TrimSpaces(sCommandLine); // Is block a parameter? iParameterIndex = -1; for (int i = 0; i < m_iParamExpectedCount; i++) { // Compare if (m_bCompareCaseSensitive) { if (strcmp(m_arrParametersExpected[i].sParameter.c_str(), sParameter.c_str()) == 0) { // We found it iParameterIndex = i; } } else { if (_stricmp(m_arrParametersExpected[i].sParameter.c_str(), sParameter.c_str()) == 0) { // We found it iParameterIndex = i; } } } // Did we find the parameter? if (iParameterIndex == -1) { // No, but maybe a part of the text is a parameter for (int i = 0; i < m_iParamExpectedCount; i++) { // Compare if (m_bCompareCaseSensitive) { if (sParameter.find(m_arrParametersExpected[i].sParameter) == 0) { // We found it iParameterIndex = i; } } else { if (MakeLowerCase(sParameter).find(MakeLowerCase(m_arrParametersExpected[i].sParameter)) == 0) { // We found it iParameterIndex = i; } } } } // Did we find any parameter? if (iParameterIndex == -1) { // Unknown parameters are used! throw UnknownParameterException(); } // Strip parameter from text block sParameter.erase(0, m_arrParametersExpected[iParameterIndex].sParameter.length()); // Do we expect a value? if (m_arrParametersExpected[iParameterIndex].bValueExpected) { // Yes, but is parameter length larget than 0? if (sParameter.length() > 0) { // Value is located in the parameter sValue = sParameter; } else { // Get next textblock, quotes are allowed sValue = GetFirstTextBlock(sCommandLine, true); // Remove value from command line sCommandLine.erase(0, sValue.length()); // Trim quotes sValue = TrimQuotes(sValue); } // Do we have a valid parameter value? if (sValue.length() <= 0) { // No, throw exception! throw ValueExpectedException(); } // Check if value is valid if (!ValidType(sValue, m_arrParametersExpected[iParameterIndex].oType)) { // Invalid type! throw WrongTypeException(); } } else { // Is there still text left in the parameter? if (sParameter.length() > 0) { // Unknown parameters are used! throw UnknownParameterException(); } } // Add parameter to used parameters list AddParameterToUsedList(iParameterIndex, sValue); } // If we get here, check if function is successful if (TrimSpaces(sCommandLine).length() > 0) { // Unknown parameters are used throw UnknownParameterException(); } } //=================================================================== int CGetOpt::GetParameterResultCount() { // Return parameter count return m_iParamUsedCount; } //=================================================================== bool CGetOpt::ParameterUsed(string sParameter) { // Declare variables bool bFound = false; // Loop all used parameters for (int i = 0; i < m_iParamUsedCount; i++) { // Check if we are working case-sensitive if (m_bCompareCaseSensitive) { // Compare case-sensitive bFound = (strcmp(sParameter.c_str(), m_arrParametersUsed[i].sParameter.c_str()) == 0) ? true : false; } else { // Compare case-insensitive bFound = (_stricmp(sParameter.c_str(), m_arrParametersUsed[i].sParameter.c_str()) == 0) ? true : false; } // Did we find the parameter? if (bFound) { // We found the parameter! return true; } } // If we get here, parameter is not used return false; } //=================================================================== Param CGetOpt::GetParameterResultInfo(string sParameter) { // Declare variables bool bFound = false; Param oParamInfo; // Loop all used parameters for (int i = 0; i < m_iParamUsedCount; i++) { // Check if we are working case-sensitive if (m_bCompareCaseSensitive) { // Compare case-sensitive bFound = (strcmp(sParameter.c_str(), m_arrParametersUsed[i].sParameter.c_str()) == 0) ? true : false; } else { // Compare case-insensitive bFound = (_stricmp(sParameter.c_str(), m_arrParametersUsed[i].sParameter.c_str()) == 0) ? true : false; } // Did we find the parameter? if (bFound) { // We found the parameter, was a value expected? if (m_arrParametersUsed[i].bValueExpected) { // Yes, return value return m_arrParametersUsed[i]; } else { // No, return empty value return oParamInfo; } } } // If we get here, parameter is not used return oParamInfo; } //=================================================================== Param CGetOpt::GetParameterResultInfo(int iIndex) { // Declare variables Param oParamInfo; // Is number in range? if ((iIndex < 0) || (iIndex > m_iParamUsedCount)) { // No value return oParamInfo; } // Return value return m_arrParametersUsed[iIndex]; } //******************************************************************* // PROTECTED / PRIVATE FUNCTIONS //******************************************************************* void CGetOpt::ResetParamData() { // Clear all data m_iParamExpectedCount = 0; m_iParamUsedCount = 0; } //=================================================================== void CGetOpt::AddParameterToUsedList(int iParameterIndex, string sValue /* = "" */) { // Is parameter already in the used list? for (int i = 0; i < m_iParamUsedCount; i++) { // Compare items if (m_bCompareCaseSensitive) { if (strcmp(m_arrParametersUsed[i].sParameter.c_str(), m_arrParametersExpected[iParameterIndex].sParameter.c_str()) == 0) { throw DoubleParametersException(); } } else { if (_stricmp(m_arrParametersUsed[i].sParameter.c_str(), m_arrParametersExpected[iParameterIndex].sParameter.c_str()) == 0) { throw DoubleParametersException(); } } } // If we get here, add parameter m_arrParametersUsed[m_iParamUsedCount++] = m_arrParametersExpected[iParameterIndex]; m_arrParametersUsed[m_iParamUsedCount-1].sValue = TrimQuotes(sValue); } //=================================================================== string CGetOpt::GetFirstTextBlock(string sText, bool bAllowQuotes /* = false */) { // Declare variables int iBlockStart = -1, iBlockEnd; string sResult; // Trim spaces sText = TrimSpaces(sText); // Should we allow quotes? if (bAllowQuotes) { // Is first character a "? if (sText.substr(0, 1) == "\"") { // Find next parameter iBlockStart = 0; iBlockEnd = sText.find('"', 1); // Don't forget to also include the quote if (iBlockEnd != -1) { iBlockEnd++; } } } // Should we search for next space? if (iBlockStart == -1) { // Start is first character iBlockStart = 0; iBlockEnd = sText.find(' ', iBlockStart); } // Is there an ending? if (iBlockEnd == -1) { // No, treat all text as value sResult = sText.substr(iBlockStart, sText.length() - iBlockStart); } else { // Yes, use value between the separators sResult = sText.substr(iBlockStart, iBlockEnd - iBlockStart); } // Return value return sResult; } //=================================================================== bool CGetOpt::ValidType(string sValue, ParameterType oParamType) { // Declare variables bool bValid = false; string sTemp; // Check which type switch (oParamType) { case PARAMETERTYPE_UNKNOWN: // All types are all-right bValid = true; break; case PARAMETERTYPE_INTEGER: // Convert to integer if ((TrimSpaces(sValue) == "0") || (atoi(sValue.c_str()) != 0)) { // Right type bValid = true; } break; case PARAMETERTYPE_BOOL: // Trim spaces sTemp = TrimSpaces(sValue); // Is it yes or no if ((MakeLowerCase(sValue) == "yes") || (MakeLowerCase(sValue) == "no")) { // Right type bValid = true; } // Is it true or false if ((MakeLowerCase(sValue) == "true") || (MakeLowerCase(sValue) == "false")) { // Right type bValid = true; } // Is it 1 or 0 if ((sValue == "1") || (sValue == "0")) { // Right type bValid = true; } break; case PARAMETERTYPE_STRING: // String is always ok bValid = true; break; default: // Unknown type bValid = false; break; } // Return value return bValid; } //=================================================================== string CGetOpt::TrimSpaces(string sValue) { // Trim at the left while ((sValue.length() > 0) && (sValue.substr(0, 1) == " ")) { // Remove the space sValue.erase(0, 1); } // Trim at the right while ((sValue.length() > 0) && (sValue.substr(sValue.length() - 1, 1) == " ")) { // Remove the space sValue.erase(sValue.length() - 1, 1); } // Return trimmed string return sValue; } //=================================================================== string CGetOpt::TrimQuotes(string sValue) { // Trim at the left while ((sValue.length() > 0) && (sValue.substr(0, 1) == "\"")) { // Remove the quotes sValue.erase(0, 1); } // Trim at the right while ((sValue.length() > 0) && (sValue.substr(sValue.length() - 1, 1) == "\"")) { // Remove the quotes sValue.erase(sValue.length() - 1, 1); } // Return trimmed string return sValue; } //=================================================================== string CGetOpt::MakeLowerCase(string sValue) { // Declare variables string sResult = sValue; // Transform the string transform(sValue.begin(), sValue.end(), sResult.begin(), tolower); // Return the result return sResult; }